/**
 * Created by no1 on 2015/7/3.
 */
//DAO(Data Access Object)是一个数据访问接口，数据访问：顾名思义就是与数据库打交道。夹在业务逻辑与数据库资源中间。

'use strict';

var CounterModel = require('./models').counter;
var F = require('../../function');

function DaoBase(data) {
  this.model = data.model;
  this.data = data;

}
//doc 为obj
/*
 @ todo 计数器
 @用于计算像id的编号自动叠加
 @ name 表名 可以不填
 */
DaoBase.prototype.getNextSequence = function* (name) {
  if (!name) {
    if (this.model.modelName) {
      name = this.model.modelName + 'id'
    } else return F.returnData(1, '没有这个模块.')
  }
  let ret = yield CounterModel.findOneAndUpdate({
    id: name
  }, {
    $inc: {seq: 1}
  }, {
    upsert: true,
    new: true
  });
  return ret.seq;
};

/*
 @todo 创建集合
 */
DaoBase.prototype.create = function* (doc) {
  let ret = yield this.model.create(doc);
  if (ret.errors) return {err: ret.errors, data: ret};
  return F.returnData(0, 'ok', ret._doc)
};

/*
 @todo 查询一条
 @query 查询条件
 @opt 参数
 */
DaoBase.prototype.getOneByQuery = function* (query, opt) {
  let ret = yield this.model.findOne(query, opt);
  if (!ret) return F.returnData(1, '没有找到');
  if (ret.errors) return F.returnData(0, ret.errors, ret);
  return F.returnData(0, '查询成功', ret._doc)
};

/**
 *@todo 查询
 *@query 查询条件
 *@fileds 筛选条件
 *@param    {Object}    query       查询条件
 *@param    {Object}    fileds      筛选条件
 *@param     int        page        页码
 *@param     int        pageSize    每页条数

 */
DaoBase.prototype.getByQuery = function* (query, fileds, page, pageSize) {
  let ret = {};
  console.time('timeByFind');
  if (page || pageSize) {
    page = page || 1;
    pageSize = pageSize || 50;
    ret = yield this.model.find(query, fileds).limit(pageSize).skip(pageSize * (page - 1));
  }
  else ret = yield this.model.find(query, fileds);
  console.timeEnd('timeByFind');
  if (!ret) return F.returnData(1, '没有找到');
  if (ret.errors) return F.returnData(0, ret.errors, ret);
  let data = [];
  if (ret instanceof Array) {
    for (let i in ret) {
      data[i] = ret[i]._doc;
    }
  }
  return F.returnData(0, '查询成功', data)
};

/**
 * todo 查询
 * @param query
 * @param opt
 * @param isPaing
 * @param isSort
 * @returns {{error, msg, data}|{error, msg}}
 */
DaoBase.prototype.getByQueryPor = function* (query, opt, isPaging, isSort) {
  let ret = {}
    , page = 1
    , pageSize = 50
    , weight = 1;

  if (isPaging != undefined) {
    page = isPaging.page || 1;
    pageSize = isPaging.pageSize || 50;
    weight += 2;
  }
  if (isSort != undefined) weight += 4;
  console.time('timeByFind');
  switch (weight) {
    case 1:
      ret = yield this.model.find(query, opt);
      break;
    case 3:
      ret = yield this.model.find(query, opt).limit(pageSize).skip(pageSize * (page - 1));
      break;
    case 5:
      ret = yield this.model.find(query, opt).sort(isSort);
      break;
    case 7:
      ret = yield this.model.find(query, opt).sort(isSort).limit(pageSize).skip(pageSize * (page - 1));
      break
    default:
      ret = yield this.model.find(query, opt);
  }
  console.timeEnd('timeByFind');
  if (!ret) return F.returnData(1, '没有找到');
  if (ret.errors) return F.returnData(0, ret.errors, ret);
  let data = [];
  if (ret instanceof Array) {
    for (let i in ret) {
      data[i] = ret[i]._doc;
    }
  }
  return F.returnData(0, '查询成功', data)
};

/*
 *@todo 查询
 *@query 查询条件
 *@fileds 筛选条件
 */
DaoBase.prototype.getCountByQuery = function* (query) {
  let ret = yield this.model.count(query);
  if (ret.errors) return F.returnData(0, ret.errors, ret);
  return F.returnData(0, '查询成功', ret);
};

/*
 @todo aggregate查询
 @pipeline 查询条件
 @opt 参数
 */
DaoBase.prototype.getByAggregate = function* (pipeline, opt) {
  if (!pipeline) return F.returnData(1, '没有参数.')
  let ret = yield this.model.aggregate(pipeline).exec();
  if (ret.errors) return F.returnData(1, ret.errors, ret);
  //return F.returnData(0, '查询成功', ret._doc)
  return F.returnData(0, '查询成功', ret)
};
/**
 @todo 添加
 @找到记录不保存
 @query 查找
 @date 添加内容
 @SeqName 计数的字段名,如code id  默认id
 */
DaoBase.prototype.findAndSave = function*(query, date, SeqName) {
  if (!(query || date)) return F.returnData(1, "参数有问题.");
  let ret = yield this.model.findOne(query);
  if (ret != null) {
    if (ret.errors) return F.returnData(1, '查找出错了', ret.errors);
    if (ret._doc._id) {
      ret._doc.thereHaveBeenData = 1;
      return F.returnData(1, '已经有数据.', ret._doc);
    }
  }
  if (SeqName) date[SeqName] = yield this.getNextSequence();
  else date.id = yield this.getNextSequence();

  ret = yield this.save(date);
  if (ret.error == 1) return F.returnData(1, ret.msg);
  return F.returnData(0, ret.msg, ret.data);
};

/**
 @todo 添加
 @找到记录不保存
 @query 查找
 @date 添加内容
 @SeqName 计数的字段名,如code id  默认id
 */
DaoBase.prototype.findAndSaveNotIncreasing = function*(query, date) {
  if (!(query || date)) return F.returnData(1, "参数有问题.");
  let ret = yield this.model.findOne(query);
  if (ret != null) {
    if (ret.errors) return F.returnData(1, '查找出错了', ret.errors);
    if (!!ret._doc._id) {
      ret._doc.thereHaveBeenData = 1;
      return F.returnData(1, '已经有数据.', ret._doc);
    }
  }
  ret = yield this.save(date);
  if (ret.error == 1) return F.returnData(1, ret.msg);
  return F.returnData(0, ret.msg, ret.data);
};

/*
 todo 保存
 */
DaoBase.prototype.save = function* (doc) {
  if (!doc) return F.returnData(1, '没有数据.');
  let obj = new this.model(doc);
  let ret = yield obj.save();
  if (ret.errors) return F.returnData(1, '保存出错');
  return F.returnData(0, '保存成功.', ret._doc);

};

/*
 @todo 修改
 @query 搜索条件
 @date 修改数据
 */
DaoBase.prototype.findAndUpdate = function* (query, data, newOne) {
  if (!query || !data) return F.returnData(1, '没有数据.');
  let ret = yield this.model.findOneAndUpdate(query, data, {new: true});
  if (!ret || ret.errors) return F.returnData(1, '更新出错', ret);
  return F.returnData(0, '更新成功.', ret._doc);
};
/**
 *
 * @param idArr
 * @returns {{error, msg, data}|{error, msg}}
 */
DaoBase.prototype.getBydistinct = function* (field, query) {
  let ret = yield this.model.distinct(field, query);
  if (!ret) return F.returnData(1, '没有找到数据');
  return F.returnData(0, '查询成功', ret);
}


/**
 *@ todo 查询一组数据
 *@param  String  Field  查找的字段
 *@param  Arary  Arr 查询的参数集合
 */
DaoBase.prototype.getByIdArr = function* (idArr) {
  let ret = yield this.model.find({id: {$in: idArr}});
  if (!ret) return F.returnData(1, '没有找到数据');
  return F.returnData(0, '查询成功', ret);
}
module.exports = DaoBase;